/****************************************************************************
 *  Copyright (C) 2018 RoboMaster.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/>.
 ***************************************************************************/
/** @file bsp_can.h
 *  @version 1.0
 *  @date Apr 2017
 *
 *  @brief receive external can device message
 *
 *  @copyright 2017 DJI RoboMaster. All rights reserved.
 *
 */
	
#ifndef __BSP_CAN_H__
#define __BSP_CAN_H__

#include "can.h"

/* CAN send and receive ID */
typedef enum
{
  CAN_3510_M1_ID       = 0x201,
  CAN_3510_M2_ID       = 0x202,
  CAN_3510_M3_ID       = 0x203,
  CAN_3510_M4_ID       = 0x204,
  CAN_PICKBOX_ROTATE_ID    = 0x205,
  CAN_PICKBOX_TRANSLATE_ID = 0x206, 
} can1_msg_id_e;

typedef enum
{
  CAN_3508_M1_ID       = 0x201,
  CAN_3508_M2_ID       = 0x202,
  CAN_3508_M3_ID       = 0x203,
	CAN_3508_M4_ID       = 0x204,
	
	CAN_3508_M5_ID       = 0x205,
  CAN_3508_M6_ID       = 0x206,
  CAN_3508_M7_ID       = 0x207,
	CAN_3508_M8_ID       = 0x208,
	
	CAN_ZGYRO_RST_ID     = 0x406,
  CAN_CHASSIS_ALL_ID   = 0x200,
  CAN_GIMBAL_ALL_ID    = 0x1ff,

	CAN_ANOTHER_MCU_ID   = 0x500,
	
} can2_msg_id_e;


/*the data communicated with another mcu*/
typedef struct
{
	uint8_t updown_flag;
	uint8_t pick_box_chassis_align;
	uint16_t can_rx_device_offline;
}mcu_rx_data_t;

typedef struct
{
	uint8_t pick_box_flag;     //(0:表示已收回)
	uint8_t pickbox_updown_flag;  //(1:表示需要抬一下, 0:表示需要降一下)
}mcu_tx_data_t;

/* can receive motor parameter structure */
#define FILTER_BUF 5
typedef struct
{
  uint16_t ecd;
  uint16_t last_ecd;
  
  int16_t  speed_rpm;
  int16_t  given_current;

  int32_t  round_cnt;
  int32_t  total_ecd;
  int32_t  total_angle;
  
  uint16_t offset_ecd;
  uint32_t msg_cnt;
  
  int32_t  ecd_raw_rate;
  int32_t  rate_buf[FILTER_BUF];
  uint8_t  buf_cut;
  int32_t  filter_rate;
} moto_measure_t;


extern moto_measure_t moto_chassis[];
extern moto_measure_t moto_yaw, moto_pit, moto_trigger;

extern moto_measure_t moto_pickbox_rotate;
extern moto_measure_t moto_pickbox_translate;

extern mcu_rx_data_t mcu_rx_data;

void encoder_data_handler(moto_measure_t* ptr, CAN_HandleTypeDef* hcan);
void encoder_data_handler2(moto_measure_t* ptr, CAN_HandleTypeDef* hcan);
void get_moto_offset(moto_measure_t* ptr, CAN_HandleTypeDef* hcan);

void can_device_init(void);
void can_receive_start(void);

void function_mode_can_func1(int16_t iq1, int16_t iq2, int16_t iq3, int16_t iq4);
void function_mode_can_func2(int16_t iq1, int16_t iq2, int16_t iq3, int16_t iq4);
void function_mode_can_func3(int16_t iq1, int16_t iq2, int16_t iq3, int16_t iq4);
void send_chassis_cur(int16_t iq1, int16_t iq2, int16_t iq3, int16_t iq4);
void send_to_another_mcu(void);
#endif
